package com.itphy.util;

import com.sun.corba.se.impl.interceptors.SlotTableStack;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * velocity模板标签 转 freemarker模板标签
 */
public class VelocityToFreemarker {
    private static List<File> files = new ArrayList<>();

    /**
     * 初始化文件集
     *
     * @param file
     */
    public static void initFilePool(File file) {
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            Arrays.stream(files).forEach(t -> {
                initFilePool(t);
            });
        }
        if (file.getName().endsWith("vm")) {
            files.add(file);
        }
    }

    public static void parseFtl(File file) {
        if (file.isFile()) {
            try {
                BufferedReader br = new BufferedReader(new FileReader(file));
                String line = "";
                StringBuilder sb = new StringBuilder();
                while ((line = br.readLine()) != null) {
                    sb.append(line);
                }
                System.out.println(parseLabel(sb.toString()));
            } catch (Exception e) {
                System.out.println(file.getName() + ":: 转换失败！");
            }
        }
    }

    public static String parseLabel(String line) {
        line = parseMsg(line);
        line = parseSet(line);
        line = parseVal(line);
        line = parseInclude(line);
        line = parseIfElse(line);

        StringBuilder sbb = new StringBuilder();
        char[] chars = line.toCharArray();
        int x = 0;
        for (int j = 0; j < chars.length; j++) {
            char aChar = chars[j];
            if (aChar == '/') {
                x = x - 2;
                sbb.append(aChar);
            } else if (aChar == '<') {
                sbb.append("\r\n");
                x = x + 1;
                for (int k = 0; k < x; k++) {
                    sbb.append(" ");
                }
                sbb.append(aChar);
            } else {
                sbb.append(aChar);
            }
        }
        return sbb.toString();
    }

    public static String parseIf(String content, String pattern) {
        String sssStart = "<#if ";
        String sssEnd = ">";
        // 创建 Pattern 对象
        Pattern r = Pattern.compile(pattern);
        // 现在创建 matcher 对象
        Matcher m = r.matcher(content);
        while (m.find()) {
            String oldMessage = m.group(0);
            String key = oldMessage.substring(oldMessage.indexOf("#if(") + 4, oldMessage.lastIndexOf(")"));
            key = key.replaceAll("!''", "");
            key = key.replaceAll("\\$\\{", "");
            key = key.replaceAll("}", "");
            String[] params = key.split("==");
            boolean flag=params.length>1 && isNumber(params[1]);
            if ((key.contains("==") || key.contains("!=")) && !key.contains("\"") && !key.contains("'")) {
                if(!flag){
                    key = key.replaceAll("==", "=='");
                    key = key.replaceAll("!=", "!='");
                }
                key = key.replaceAll(" &&", "' &&");
                key = key.replaceAll(" \\|\\|", "' \\|\\|");
                key = key + "'";
            }
            String newMessage = sssStart + key + sssEnd;
            content = content.replace(oldMessage, newMessage);
        }
        return content;
    }

    public static boolean isNumber(String num){
        try {
            Integer.parseInt(num);
            return true;
        }catch (Exception e){
            return false;
        }
    }

    public static String parseElseIf(String content) {
        String pattern = "#elseif\\([\\| \\'\\&\\$\\!\\{\\}\\=0-9a-zA-Z\\.\\_]+\\)";
        String sssStart = "<#elseif ";
        String sssEnd = ">";
        // 创建 Pattern 对象
        Pattern r = Pattern.compile(pattern);
        // 现在创建 matcher 对象
        Matcher m = r.matcher(content);
        while (m.find()) {
            String oldMessage = m.group(0);
            String key = oldMessage.substring(oldMessage.indexOf("#elseif(") + 8, oldMessage.lastIndexOf(")"));
            key = key.replaceAll("!''", "");
            key = key.replaceAll("\\$\\{", "");
            key = key.replaceAll("}", "");
            String[] params = key.split("==");
            boolean flag=params.length>1 && isNumber(params[1]);
            if ((key.contains("==") || key.contains("!=")) && !key.contains("\"") && !key.contains("'")) {
                if(!flag){
                    key = key.replaceAll("==", "=='");
                    key = key.replaceAll("!=", "!='");
                }
                key = key.replaceAll(" &&", "' &&");
                key = key.replaceAll(" \\|\\|", "' \\|\\|");
                key = key + "'";
            }

            String newMessage = sssStart + key + sssEnd;
            content = content.replace(oldMessage, newMessage);
        }
        return content;

    }

    public static String parseIfElse(String line) {
        line = line.replaceAll("elseif", "[e-l-s-e-i-f]");
        line = line.replaceAll("#else", "<#else>");
        line = line.replaceAll("\\[e-l-s-e-i-f\\]", "elseif");
        line = parseIf(line, "#if\\([\\| '\\&\\$\\!\\\"\\{\\}\\=0-9a-zA-Z\\.\\_]+\\)");
        line = parseElseIf(line);
        line = line.replaceAll("#end", "</#if>");
        line = line.replaceAll("#macro", "<#macro");
        return line;
    }

    public static String parseMsg(String line) {
        String pattern = "#message\\('[0-9a-zA-Z\\.\\_]+'\\)";
        String sssStart = "<@message code=\"";
        String sssEnd = "\" locale=\"${locale}\"/>";
        Pattern r = Pattern.compile(pattern);
        Matcher m = r.matcher(line);
        while (m.find()) {
            String oldMessage = m.group(0);
            String key = oldMessage.substring(oldMessage.indexOf("'") + 1, oldMessage.lastIndexOf("'"));
            String newMessage = sssStart + key + sssEnd;
            line = line.replace(oldMessage, newMessage);
        }
        return line;
    }

    public static String parseVal(String line) {
        String pattern = "\\$!\\{[\\[\\].\\{\\}\\(\\)\",0-9a-zA-Z\\.\\_]+\\}";
        String sssStart = "${";
        String sssEnd = "!''}";
        Pattern r = Pattern.compile(pattern);
        Matcher m = r.matcher(line);
        while (m.find()) {
            String oldMessage = m.group(0);
            String key = oldMessage.substring(oldMessage.indexOf("$!{") + 3, oldMessage.lastIndexOf("}"));
            key = key.replace("TemVal.", "");
            String newMessage = sssStart + key + sssEnd;
            line = line.replace(oldMessage, newMessage);
        }
        return line;
    }

    public static String parseSet(String line){
        //#set($prevPage = ${data.currentPage} - 1)
        //
        //<#assign x=”freemarker”>
        String pattern="(?<=#set\\(\\$)([a-zA-Z0-9]+)";
        Matcher matcher = Pattern.compile(pattern).matcher(line);
        List<String> list=null;
        while (matcher.find()) {
            if(Objects.isNull(list)){
                list=new ArrayList<>();
            }
            list.add(matcher.group(0));
        }
        for (int i = 0; i < list.size(); i++) {
            line = line.replaceAll("#set\\(\\$" + list.get(i), "<#assign " + list.get(i).substring(1));
        }
        return line;
    }

    public static String parseForeach(String line){
        /**
         * <#list buzList as item>
         *    <option value="${item.value!''}">${item.desc!''}</option>
         * </#list>
         *
         * #foreach($foo in [$!offsetStart..$offsetEnd])
         *
         */
        return line;
    }

    public static String parseInclude(String line) {
        line = line.replaceAll("#parse", "#include");
        return line;
    }

    public static void start(String path) {
        initFilePool(new File(path));
        files.stream().forEach(t -> {
            parseFtl(t);
        });
    }

    public static void main(String[] args) {
        start("C:\\Users\\admin\\Desktop\\member\\velocity\\test");
//            parseSet("#set($prevPage = ${data.currentPage} - 1)");
        }
}
